package com.bbird.od.finance.service.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.bbird.od.finance.service.models.*;
import com.bbird.od.finance.service.models.type.BankCostType;
import com.bbird.od.finance.service.models.type.BankType;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ziyang Kuang
 * @date 2020/11/16
 * @describe
 */

@Slf4j
@Getter
public class FlowExcelListener<T> extends AnalysisEventListener<T> {

    private List<T> dataList = new ArrayList<>();
    private BankType bankType = null;
    private String fileName = null;

    public FlowExcelListener(BankType bankType, String fileName){
        this.bankType = bankType;
        this.fileName = fileName;
    }

    @Override
    public void invoke(T flow, AnalysisContext analysisContext) {
        if (isEndData(flow)) {
            return;
        }
        if (isFilterData(flow)) {
            return;
        }
        dataList.add(flow);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }

    @Override
    public void onException(Exception exception, AnalysisContext context) {
        // 如果是某一个单元格的转换异常 能获取到具体行号
        log.error("[{}] 解析异常:", this.getBankType().getLabel(), exception);
        // 如果要获取头的信息 配合invokeHeadMap使用
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            String errMsg = MessageFormat.format("[{0}], [{1}], 第{2}行, 第{3}列解析异常"
                    , this.bankType.getLabel(), this.fileName, excelDataConvertException.getRowIndex(), excelDataConvertException.getColumnIndex());
            log.error("[{}] 解析异常, 转换异常: {}", this.getBankType().getLabel(), errMsg);
        }
    }

    private boolean isEndData(T flow) {
        if (flow instanceof ERPFlow) {
            if (StringUtils.isBlank(((ERPFlow) flow).getConcatCompanyNumber())) {
                return true;
            }
        } else if (flow instanceof BankFlow) {
            Method method = null;
            try {
                method = flow.getClass().getMethod("getBusinessOrderNumber");
                Object businessOrderNumber = method.invoke(flow);
                if (businessOrderNumber == null) {
                    return true;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return true;
            }
        } else if (flow instanceof DeliveryFlow) {
            if (StringUtils.isBlank(((DeliveryFlow) flow).getHomeOrderNumber())) {
                return true;
            }
        }
        return false;
    }

    private boolean isFilterData(T flow) {

        // ERP数据过滤SK和FK开头的数据
        if (flow instanceof ERPFlow) {
            if (((ERPFlow)flow).getHomeOrderNumber().toUpperCase().startsWith("SK")
                    || ((ERPFlow)flow).getHomeOrderNumber().toUpperCase().startsWith("FK")) {
                return true;
            }
        }

        // 拼多多只需对"交易收入、优惠券结算、退款"进行对账
        if (flow instanceof PDDBankFlow) {
            if (((PDDBankFlow) flow).getCostType() != BankCostType.PDD_TRADE_INCOME
                    && ((PDDBankFlow) flow).getCostType() != BankCostType.PDD_COUPON_SETTLEMENT
                    && ((PDDBankFlow) flow).getCostType() != BankCostType.PDD_REFUND) {
                return true;
            }
        }

        // 天猫只需对"交易付款、在线支付"进行对账
        if (flow instanceof TMBankFlow) {
            if (((TMBankFlow) flow).getCostType() != BankCostType.TM_TRADE_INCOME
                    && ((TMBankFlow) flow).getCostType() != BankCostType.TM_ONLINE_PAY) {
                return true;
            }
        }

        return false;
    }
}
